package haco.syncremotefile.utils;

import cn.hutool.extra.ftp.Ftp;
import haco.syncremotefile.modal.FTPFileL;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.net.ftp.FTPFile;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * @author wangyuwei
 * @history 2021-06-02 16:13
 */
@Slf4j
@Service
public class Download4SourceFtp implements  Dowload4Source {

    private static  final String  ENTER_LOCAL_ACTIVE_MODE = "enterLocalActiveMode";

    @Autowired
    SourceConfig sourceConfig;

    @Value("${localTmpPath}")
    String localTmpPath;




    /**
     * setConnectTimeout()用于设置终端 Socket 与 FTP 服务器建立连接这个过程的超时时间。
     * setDefaultTimeout()用于设置终端的传输控制命令的 Socket 的 SoTimeout，即针对传输控制命令的 Socket 的输入流做读取操作时每次陷入阻塞的超时时间。
     * setSoTimeout()作用跟上个方法一样，区别仅在于该方法设置的超时会覆盖掉上个方法设置的值。
     * setDataTimeout()用于设置终端的传输数据的 Socket 的 Sotimeout，即针对传输文件数据的 Socket 的输入流做读取操作时每次陷入阻塞的超时时间。
     * setControlKeepAliveTimeout()用于设置当处于传输数据过程中，按指定的时间阈值定期让传输控制命令的 Socket 发送一个无操作命令 NOOP 给服务器，让它 keep alive。
     * setControlKeepAliveReplyTimeout()：只有调用上个方法后，该方法才能生效，用于设置在传输数据这个过程中，暂时替换掉传输控制命令的 Socket 的 SoTimeout，传输过程结束恢复这个 Socket 原本的 SoTimeout。
     *
     * @param source
     * @return
     */
    public Ftp getFtpConnect( SourceConfig.Task.Source source){
        log.info("连接ftp{}",source.toString());
        Ftp ftp = new Ftp(source.getIp(),source.getPort(),source.getUsername(),source.getPassword());
        if(ENTER_LOCAL_ACTIVE_MODE.equals(source.getMode())){
            ftp.getClient().enterLocalActiveMode();
        }else{
            ftp.getClient().enterLocalPassiveMode();
        }
        log.info("已获取ftp连接");
        return ftp ;
    }





    @Override
    public File downloadLocal() {
        SourceConfig.Task.Source source = sourceConfig.getTasks().get(0).getSource();
        SourceConfig.Task.Target target = sourceConfig.getTasks().get(0).getTarget();

        Ftp ftp = new Ftp(source.getIp(),source.getPort(),source.getUsername(),source.getPassword());

        List<String> ls = ftp.ls("/");
        ftp.getClient().enterLocalPassiveMode();
        ftp.mkDirs("/home/vsftpd/testdir");



        List<String> ls1 = ftp.ls("/home/vsftpd");
        boolean upload = ftp.upload("/home/vsftpd", "testjson",new File("C:\\Users\\wangyuwei03\\package-lock.json"));
        System.out.println("upload:"+upload);
        System.out.println("ls1:"+ls1);
        ls.forEach(i-> System.out.println(i));
        try {
            ftp.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }


    /**
     * 获取所有文件信息
     * @param ftp
     * @param sourcePath
     * @param ftpfiles
     * @return
     */

    public List<FTPFileL> getAllFilePath(Ftp ftp, String sourcePath, String relativePath , List<FTPFileL> ftpfiles,
                                         int sourceNum){
        if(ftpfiles == null) {
            ftpfiles = new ArrayList<FTPFileL>();
        }
        try {
            for (FTPFile ftpFile : ftp.lsFiles(PathUtils.get(sourcePath,relativePath), null)) {
                if (false == ftpFile.isDirectory()) {
                    FTPFileL ftpFileL = new FTPFileL();
                    BeanUtils.copyProperties(ftpFile, ftpFileL);
                    ftpFileL.setPath(relativePath);
                    ftpFileL.setSourceNum(sourceNum);
                    ftpfiles.add(ftpFileL);

                } else {
                    String fullPath = PathUtils.get(relativePath, ftpFile.getName());
                    getAllFilePath(ftp, sourcePath,fullPath, ftpfiles,sourceNum);
                }
            }
        }catch (Exception e){
            e.printStackTrace();
            log.error("获取数据目录失败："+  sourcePath);
        }
        return ftpfiles;
    }


    public void ftpConnectClose(Ftp ftp){
        try{
            if(ftp != null){
                ftp.close();
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}
